home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- FILENAME: VIEW_UT.CPP
- AUTHOR : JAKE HILL
- DATE : 12/1/94
-
- Copyright (c) 1994 by Jake Hill:
- If you use any part of this code in your own project, please credit
- me in your documentation and source code. Thanks.
- ********************************************************************/
-
- #define STEP_HEIGHT 24
-
- #define C
-
- #include "view.h"
- #include "trig.h"
-
- extern short MaxNode;
-
- extern short chksect;
- extern short tellsect;
-
- extern short player_ssector;
- extern short last_height;
-
- /* This function returns TRUE it the player is on the right
- * of the node indexed by node_num.
- */
-
- char OnRightNode(short node_num)
- {
- node *ThisNode = PNode_Array[node_num];
- long x1 = ThisNode->x;
- long y1 = ThisNode->y;
- long x2 = x1 + ThisNode->dx;
- long y2 = y1 + ThisNode->dy;
-
- if (((x1 - x2) * (Py - y2)) >= ((y1 - y2) * (Px - x2)))
- return 1;
- return 0;
- }
-
-
- /* This function returns TRUE it the player is on the right
- * of the line segment created by the vertexes indexed by from, and to.
- */
-
- char OnRightLine(short from, short to)
- {
- long x1, y1, x2, y2;
- vertex *Vertex;
-
- Vertex = &Vertex_Array[from];
- x1 = Vertex->x;
- y1 = Vertex->y;
- Vertex = &Vertex_Array[to];
- x2 = Vertex->x;
- y2 = Vertex->y;
-
- if (((x1 - x2) * (Py - y2)) >= ((y1 - y2) * (Px - x2)))
- return 1;
- return 0;
- }
-
- /* Note concerning LeftSideInCone & RightSideInCone.
- * These functions are based on the quadrants that the
- * view cone intersects. The minimum resolution is an
- * entire quadrant. This is not very accurate, and therefore
- * does not cull out as many nodes as would be ideal, but it
- * is a quick and dirty method that is fairly effective.
- * It could DEFINATELY be improved upon.
-
- * This function returns TRUE if the LEFT Child Node
- * of the node indexed by node_num is in the view cone.
- */
-
- char LeftSideInCone(short node_num)
- {
- if ( LeftAngle < 0x4000 ) {
- if (PNode_Array[node_num]->lx2 > Px)
- return 1;
- } else if (LeftAngle < 0x8000) {
- if (PNode_Array[node_num]->ly2 > Py)
- return 1;
- } else if (LeftAngle < 0xC000) {
- if (PNode_Array[node_num]->lx1 < Px)
- return 1;
- } else {
- if (PNode_Array[node_num]->ly1 < Py)
- return 1;
- }
-
- return 0;
- }
-
- /* This function returns TRUE if the RIGHT Child Node
- * of the node indexed by node_num is in the view cone.
- */
-
- char RightSideInCone(short node_num)
- {
- if (LeftAngle < 0x4000) {
- if (PNode_Array[node_num]->rx2 > Px)
- return 1;
- } else if (LeftAngle < 0x8000) {
- if (PNode_Array[node_num]->ry2 > Py)
- return 1;
- } else if (LeftAngle < 0xC000) {
- if (PNode_Array[node_num]->rx1 < Px)
- return 1;
- } else {
- if (PNode_Array[node_num]->ry1 < Py)
- return 1;
- }
-
- return 0;
- }
-
- /**********************/
- /* This function obtains data common to all segs in the SSector
- * as well as doing the backface elimination via OnRight.
- */
-
- short SetPlayerSSector(short SS, short *ssector, short *height)
- {
- short LineSide, Sector;
- segment *ThisSeg;
- sector *ThisSector;
-
- ThisSeg = &Seg_Array[SSector_Array[SS].first_seg];
-
- LineSide = ThisSeg->line_side;
-
- #ifdef __GNUC__
- Sector = Side_Array[Line_Array[ThisSeg->line].side[LineSide]].sector;
- #else
- Sector = Side_Array[Line_Array[ThisSeg->xline].side[LineSide]].sector;
- #endif
-
- /* Load the floor and ceiling height. */
-
- ThisSector = &Sector_Array[Sector];
-
- /* ThisSector might be better below */
- *ssector = SS; /* Used to stop wall pass-through */
- *height = ThisSector->floor_ht;
- }
-
- short FindNode(short node_num, short *ssector, short *height)
- {
- /* If this node is a SSECTOR then we've found the player. */
-
- if (node_num & 0x8000) {
- SetPlayerSSector(node_num & 0x7fff, ssector, height);
- return;
- }
-
- if (!OnRightNode(node_num)) {
- if (LeftSideInCone(node_num))
- FindNode(PNode_Array[node_num]->left, ssector, height);
- else if (RightSideInCone(node_num))
- FindNode(PNode_Array[node_num]->right, ssector, height);
- } else {
- if (RightSideInCone(node_num))
- FindNode(PNode_Array[node_num]->right, ssector, height);
- else if (LeftSideInCone(node_num))
- FindNode(PNode_Array[node_num]->left, ssector, height);
- }
- }
-
-
- /* This function sets the view's x,y, height, and angle values. */
-
- void SetView(short *xi, short *yi, short *hi, unsigned short *ai)
- {
- short old_px, old_py, x, y, h;
- unsigned short old_pangle, a;
- static start = 2;
- #ifdef __GNUC__
- short ssector, height;
- #else
- short s_sector, height;
- #endif
-
- x = *xi;
- y = *yi;
- h = *hi;
- a = *ai;
-
- old_px = Px;
- old_py = Py;
- old_pangle = Pangle;
- Px = x;
- Py = y;
- Ph = h;
- Pangle = a;
- LeftAngle = Pangle + 0x2000;
-
- /* It's probably possible to find out the new sector by simply
- * searching for the line that was crossed and enter the structures
- * from there.
- */
-
- if (start != 2) { /* SetView not called from OpenWAD */
- #ifdef __GNUC__
- ssector = -1;
- FindNode(MaxNode, &ssector, &height);
- if (ssector == -1) {
- #else
- FindNode(MaxNode, &s_sector, &height);
- if (s_sector == -1) {
- #endif
- printf("Didn't find current ssector!\n");
- exit(1);
- }
- }
- if (start) {
- start--; /* The very first call here after loading is OK */
- last_height = height;
- #ifdef __GNUC__
- player_ssector = ssector;
- printf("You start in sector %d at height %d\n", (int)ssector, (int)height);
- #else
- player_ssector = s_sector;
- printf("You start in sector %d at height %d\n", (int)s_sector, (int)height);
- #endif
- } else {
- #ifdef __GNUC__
- if (player_ssector != ssector) {
- if (tellsect)
- printf("Entering new sector %d at height %d\n", (int)ssector, (int)height);
- #else
- if (player_ssector != s_sector) {
- if (tellsect)
- printf("Entering new sector %d at height %d\n", (int)s_sector, (int)height);
- #endif
- if ((height - last_height <= STEP_HEIGHT) || !chksect) {
- last_height = height;
- #ifdef __GNUC__
- player_ssector = ssector;
- #else
- player_ssector = s_sector;
- #endif
- } else {
- if (tellsect)
- printf("Disallowed height difference!\n");
- Px = old_px;
- Py = old_py;
- Pangle = old_pangle;
- LeftAngle = Pangle + 0x2000;
- }
- }
- }
-
- SinPangle = sine(0x00-Pangle);
- CosPangle = cosine(0x00-Pangle);
- *xi = Px;
- *yi = Py;
- *hi = Ph;
- *ai = Pangle;
- }
-
- #if 0
- /* This function updates the view's x,y, height, and angle values. */
-
- void UpdateView(short dx, short dy, short dh, unsigned short da)
- {
- Px += dx;
- Py += dy;
- Ph += dh;
- Pangle += da;
- LeftAngle = Pangle + 0x2000;
- SinPangle = sine(0x00-Pangle);
- CosPangle = cosine(0x00-Pangle);
- }
- #endif
-
-
- /* This function returns the view's x,y height and angle values. */
-
- void GetView(short *x, short *y, short *h, unsigned short *a)
- {
- *x = Px;
- *y = Py;
- *h = Ph;
- *a = Pangle;
- }
-